package com.aps.page;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.springframework.jdbc.core.JdbcTemplate;

import com.aps.util.JdbcQueryUtil;

import lombok.Data;

/**
 * @author liaoguangan
 * @description <用于JdbcTemplate MySQL分页查询>
 * @date 2018/4/9 14:13
 */
@Data
public class Pagination<T> implements Serializable {

    //当前页码
    private Integer number;

    //总条数
    private Long totalElements;

    //pageSize
    private Integer size;

    //内容
    private List<T> content;

    public Pagination<T> search(JdbcTemplate jdbcTemplate, Class<T> tCls, String sql,
                                Object[] params, BaseQuery baseQuery, String alias) {
        int num = baseQuery.getPageNum();
        int size = baseQuery.getPageSize();

        this.setNumber(num);
        this.setSize(size);

        sql = this.build(sql, baseQuery.getItems(), baseQuery.getUnionType(), alias,
                baseQuery.getSortName(), baseQuery.getSortType());

        //查询总条数
        Long total = jdbcTemplate.queryForObject(this.getTotalSql(sql), params, Long.class);
        this.setTotalElements(total);

        List<T> rs = new JdbcQueryUtil<T>(tCls).queryList(jdbcTemplate,
                this.getLimitSql(sql, num, size), params);
        this.setContent(rs);

        return this;
    }

    private String countSql(String sql) {
        sql = sql.toLowerCase();
        int startIndex = sql.indexOf("select ");
        int endIndex = sql.indexOf(" from");
        String tempSql = sql.replace(sql.subSequence(startIndex + 7, endIndex + 1), " 1 ");
        int groupIndex = tempSql.lastIndexOf("group");
        return -1 == groupIndex ? tempSql : tempSql.substring(0, groupIndex);
    }

    private String getTotalSql(String sql) {
        return "select count(*) from (" + this.countSql(sql) + ") temp";
    }

    private String getLimitSql(String sql, int num, int size) {
        return sql + " limit " + (num * size) + "," + size;
    }

    private String build(String sql, List<QueryItem> items, Map<String, UnionType> unionTypeMap,
                         String alias, String sortName, String sortType) {
        if (null == items || items.size() == 0) return sql;
        sql += " where " + alias + ".is_deleted=false ";
        int index = 0;
        for (QueryItem item : items) {
            String type = null == unionTypeMap ? " and " : (null == unionTypeMap
                    .get(item.getQueryKey()) ? " and " : unionTypeMap.get(item.getQueryKey())
                    .toString());

            if (item.getConditionType().equals(ConditionType.LIKE)) {
                item.setQueryValue(
                        " '%" + (null == item.getQueryValue() ? "" : item.getQueryValue()) + "%' ");
            }
            if (index == 0) {
                sql += " and (";
            } else {
                sql += type;
            }
            sql += " " + alias + "." + item.getQueryKey() + " " + item.getConditionType().getDesc()
                    + " " + item.getQueryValue() + " ";
            index++;
        }

        sql += ")";

        if (null != sortName && null != sortType) {
            sql += " order by " + alias + "." + sortName + " " + sortType;
        }

        return sql;
    }
}